package com.plian.system.controller.wf;

import com.plian.Tools.base.BaseController;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.config.exception.MyRuntimeException;
import com.plian.system.helper.wf.WorkflowModelVariableKeySetHelper;
import com.plian.system.model.CommonCode;
import com.plian.system.model.ListResult;
import com.plian.system.model.ObjResult;
import org.flowable.engine.ManagementService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.ui.modeler.domain.AbstractModel;
import org.flowable.ui.modeler.domain.Model;
import org.flowable.ui.modeler.serviceapi.ModelService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.security.auth.login.LoginException;
import java.nio.charset.StandardCharsets;
import java.util.List;

@RestController
@RequestMapping("api/model")
public class ModelBpmnController extends BaseController {
    @Autowired(required =false)
    private RepositoryService repositoryService;

    @Autowired
    private ModelService modelService;

    @Autowired(required =false)
    private ManagementService managementService;

    @PostMapping(value = "/list")
    public ListResult<Model> list(@RequestBody(required = false) PageData pd) {
        String filterText = pd.getString("filterText");
        List<Model> byModelTypeAndFilter = modelService.findByModelTypeAndFilter(AbstractModel.MODEL_TYPE_BPMN, filterText, "modifiedDesc");
        if (byModelTypeAndFilter != null && byModelTypeAndFilter.size() > 0) {
            StringBuilder ids = new StringBuilder();
            byModelTypeAndFilter.forEach(model -> {
                ids.append("'").append(model.getKey()).append("'").append(",");
            });
            String id = ids.substring(0, ids.length() - 1);
            List<Deployment> deploymentList = repositoryService.createNativeDeploymentQuery()
                .sql("SELECT * FROM " + managementService.getTableName(Deployment.class)
                    + " WHERE KEY_ IN "
                    + "(" + id + ") ")
                //.parameter("tenantId", FlowableModelerProperties.getTenantId())
                .list();
            for (Deployment deployment : deploymentList) {
                for (Model model : byModelTypeAndFilter) {
                    if (model.getKey().equals(deployment.getKey())) {
                        model.setIsDeploy(1);
                    }
                }
            }
        }
        ListResult<Model> result = new ListResult<>(CommonCode.SUCCESS);
        result.setList(byModelTypeAndFilter);
        return result;
    }

    @PostMapping(value = "/deploy")
    @Transactional
    public ObjResult bpmnModelDeploy(@RequestBody PageData pd) throws LoginException {
        String modelId = pd.getString("modelId");
        Model model = modelService.getModel(modelId);
        if (model == null) {
            throw new MyRuntimeException(new ObjResult("模型不存在"));
        }
        byte[] bpmnXML = modelService.getBpmnXML(model);
        repositoryService.addModelEditorSource(modelId, bpmnXML);
        String processName = model.getName() + ".bpmn20.xml";
        try {
            Deployment deployment = repositoryService
                .createDeployment()
                .name(model.getName())
                .key(model.getKey())
                .addString(processName, new String(bpmnXML, StandardCharsets.UTF_8))
                .tenantId(null)
                .deploy();
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult();
            WorkflowModelVariableKeySetHelper.update(processDefinition.getId(), repositoryService);
        } catch (Exception e) {
            return new ObjResult(CommonCode.ERROR);
        }
        return new ObjResult(CommonCode.SUCCESS);
    }

    @RequestMapping("/update-form-type")
    public ObjResult updateFormType(@RequestBody PageData pd) {
        String modelId = pd.getString("modelId");
        int formType = Integer.parseInt(pd.getString("formType"));
        Model model = modelService.getModel(modelId);
        model.setFormType(formType);
        modelService.save(model);
        return new ObjResult(CommonCode.SUCCESS);
    }

    @RequestMapping("/name-form-type")
    public ListResult<PageData> formtypeName(){
        ListResult<PageData> result = new ListResult<>(CommonCode.SUCCESS);
        List<PageData> list = modelService.formtypeName();
        result.setList(list);
        return  result;
    }
}
